﻿using Inovout.Cloud.DataStore.Models;
using Inovout.Cloud.DataStore.Services;
using Inovout.Cloud.DataWarehouse.Models;
using Inovout.Cloud.DataWarehouse.Services;
using Inovout.Cloud.DataWarehouse.Web.Models;
using Inovout.Cloud.DataWarehouse.Web.Utility;
using Newtonsoft.Json.Linq;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;
using System.Web.Http;

namespace Inovout.Cloud.DataWarehouse.Web.Controllers
{
    public class DataCollectionController : ApiController
    {
        private IDataCollectionService dataCollectionService;
        private ITableService tableService;
        private IDatabaseService databaseService;

        public DataCollectionController()
        {
            this.dataCollectionService = ComponentRegistry.Resolve<IDataCollectionService>();
            this.tableService = ComponentRegistry.Resolve<ITableService>();
            this.databaseService = ComponentRegistry.Resolve<IDatabaseService>();
        }

        static DataCollectionController()
        {
            AutoMapper.Mapper.CreateMap<BaseInfo, DataCollection>();
            AutoMapper.Mapper.CreateMap<DataCollection, BaseInfo>();
        }

        //GET https://www.xx.com/dataWarehouse/v1/dataCollection
        [Route("v1/dataCollection")]
        public List<BaseInfo> Get()
        {
            List<BaseInfo> list = null;
            IEnumerable<DataCollection> dataCollections = dataCollectionService.FindAll();

            if (dataCollections != null && dataCollections.Count() > 0)
            {
                list = new List<BaseInfo>();
                foreach (DataCollection dataCollection in dataCollections)
                {
                    BaseInfo b = new BaseInfo();
                    b.Name = dataCollection.Name;
                    b.CreatedTime = dataCollection.CreatedTime;
                    list.Add(b);
                }
            }
            return list;
        }

        //GET https://www.xx.com/dataWarehouse/v1/dataCollection/{dataCollectionName}
        [Route("v1/dataCollection/{dataCollectionName}")]
        public BaseInfo Get(string dataCollectionName)
        {
            BaseInfo baseInfo = null;
            if (dataCollectionName != null)
            {
                DataCollection dataCollection = dataCollectionService.FindByName(dataCollectionName.ToLower());
                StringBuilder strBuilder = new StringBuilder();
                if (dataCollection != null)
                {
                    baseInfo = new BaseInfo();
                    baseInfo.Name = dataCollection.Name;
                    baseInfo.CreatedTime = dataCollection.CreatedTime;
                }
            }
            return baseInfo;
        }

        //POST https://www.xx.com/dataWarehouse/v1/dataCollection
        //每次调用都会创建一个新的dataCollection
        [Route("v1/dataCollection")]
        public BaseInfo Post(DataCollectionInfo dataCollectionInfo)
        {
            //1.根据dataView名称查询dataView信息
            //2.根据查询出来的dataView的属性值判断发布的属性是否合法
            //3.构建dataCollection对象
            //4.保存dataCollection对象
            BaseInfo baseInfo = null;
            if (dataCollectionInfo == null)
            {
                return baseInfo;
            }

            DataCollection dataCollection = CreateDataCollection(dataCollectionInfo);

            if (dataCollection == null)
            {
                return null;//发布的DataView有不存在的
            }
            return BindToViewModel(dataCollection);
        }

        private DataCollection CreateDataCollection(DataCollectionInfo dataCollectionInfo)
        {
            //第一步
            DataCollection dataCollectionExist = dataCollectionService.FindByName(dataCollectionInfo.Name);
            if (dataCollectionExist != null)
            {
                //已经存在了
                return dataCollectionExist;
            }

            //根据database名称查询database对象
            Database database = databaseService.FindByName(dataCollectionInfo.DatabaseName);

            //根据dataViewName查询关联的RootDataView
            Table table = tableService.FindByName(database, dataCollectionInfo.TableName);
            if (table == null)
            {
                return null;//TODO 告诉客户端dataView不存在
            }
            Iesi.Collections.Generic.ISet<Property> tableProperties = table.Properties;
            Dictionary<string, Property> dictionary = new Dictionary<string, Property>();

            foreach (Property d in tableProperties)
            {
                dictionary.Add(d.Name.ToLower(), d);
            }

            ArrayList list = dataCollectionInfo.DataCollectionProperties;
            Iesi.Collections.Generic.ISet<DataCollectionProperty> properties = new Iesi.Collections.Generic.HashedSet<DataCollectionProperty>();
            DataCollection dataCollection = new DataCollection();//先创建好，后面有对象会引用
            dataCollection.IsPublish = dataCollectionInfo.IsPublish;

            dataCollection.DisplayProperties = dataCollectionInfo.DisplayProperties;//TODO 需要验证properties是否为table中的

            foreach (JObject jObject in list)
            {
                JToken jToken = jObject["propertyName"];
                if (jToken != null)
                {
                    DataCollectionPropertyInfo p = jObject.ToObject<DataCollectionPropertyInfo>();

                    DataViewCollectionProperty pc = new DataViewCollectionProperty();
                    pc.Formatter = p.Formatter;
                    pc.DataCollection = dataCollection;
                    pc.Property = dictionary[p.PropertyName.ToLower()];
                    pc.Type = CommonUtils.viewTypeTransform(pc.Property.FieldType);
                    properties.Add(pc);

                }
                else
                {
                    //父子关系
                    DataCollectionRelationProperty pr = new DataCollectionRelationProperty();
                    DataCollectionRelationPropertyInfo p = jObject.ToObject<DataCollectionRelationPropertyInfo>();
                    DataCollection child = dataCollectionService.FindByName(p.DataCollectionName);
                    if (child == null)
                    {
                        return null;//发布的数据集不存在 TODO
                    }
                    pr.DataCollection = dataCollection;
                    pr.RelationDataCollection = child;
                    pr.Type = CommonUtils.stringTransform(p.Type);

                    if (p.DataCollectionRelationConditions == null || p.DataCollectionRelationConditions.Count == 0)
                    {
                        return null;//没有指定条件
                    }
                    Iesi.Collections.Generic.ISet<DataCollectionRelationCondition> conditions = new Iesi.Collections.Generic.HashedSet<DataCollectionRelationCondition>();
                    foreach (DataCollectionRelationConditionInfo dataCollectionRelationConditionInfo in p.DataCollectionRelationConditions)
                    {
                        DataCollectionRelationCondition dataCollectionRelationCondition = new DataCollectionRelationCondition();
                        dataCollectionRelationCondition.DataCollectionRelationProperty = pr;

                        //不为空，则表示是两个小条件连接成一个大条件
                        if (dataCollectionRelationConditionInfo.ConditionOperation != null && dataCollectionRelationConditionInfo.ConditionOperation.Length > 0)
                        {
                            dataCollectionRelationCondition.ConditionOperation = CommonUtils.stringTransformOpertion(dataCollectionRelationConditionInfo.ConditionOperation);
                        }

                        dataCollectionRelationCondition.IsValueCondition = dataCollectionRelationConditionInfo.IsValueCondition;
                        dataCollectionRelationCondition.Operation = CommonUtils.stringTransformOpertion(dataCollectionRelationConditionInfo.Operation);
                        dataCollectionRelationCondition.TargetValue = dataCollectionRelationConditionInfo.TargetValue;

                        if (dataCollectionRelationConditionInfo.SourceDataCollectionProperty != null)
                        {
                            DataViewCollectionProperty pc = new DataViewCollectionProperty();
                            pc.DataCollection = dataCollection;
                            pc.Property = dictionary[dataCollectionRelationConditionInfo.SourceDataCollectionProperty.ToLower()];
                            pc.Type = CommonUtils.viewTypeTransform(pc.Property.FieldType);
                            dataCollectionRelationCondition.SourceDataCollectionProperty = pc;
                        }

                        if (dataCollectionRelationConditionInfo.TargetDataCollectionProperty != null)
                        {
                            Iesi.Collections.Generic.ISet<DataCollectionProperty> dataCollectionProperties = child.Properties;
                            foreach (DataCollectionProperty dataCollectionProperty in dataCollectionProperties)
                            {
                                if (dataCollectionProperty is DataViewCollectionProperty)
                                {
                                    DataViewCollectionProperty tmpDvP = (DataViewCollectionProperty)dataCollectionProperty;
                                    if (dataCollectionRelationConditionInfo.TargetDataCollectionProperty.ToLower().Equals(tmpDvP.Property.Name.ToLower()))
                                    {
                                        dataCollectionRelationCondition.TargetDataCollectionProperty = tmpDvP;
                                        break;
                                    }
                                }
                            }
                            if (dataCollectionRelationCondition.TargetDataCollectionProperty == null)
                            {
                                return null;//发布的target字段有错
                            }
                        }
                        conditions.Add(dataCollectionRelationCondition);
                    }
                    pr.Conditions = conditions;
                    properties.Add(pr);
                }
            }

            if (properties.Count > 0)
            {
                dataCollection.Properties = properties;
                dataCollection.Name = dataCollectionInfo.Name;
                dataCollection.Table = table;

                if (dataCollectionInfo.DataCollectionViewTemplate != null)
                {
                    DataCollectionViewTemplate dataCollectionViewTemplate = new DataCollectionViewTemplate();
                    dataCollectionViewTemplate.DataCollection = dataCollection;
                    dataCollectionViewTemplate.LinkUrl = dataCollectionInfo.DataCollectionViewTemplate.LinkUrl;
                    dataCollectionViewTemplate.Summary = dataCollectionInfo.DataCollectionViewTemplate.Summary;
                    dataCollectionViewTemplate.Title = dataCollectionInfo.DataCollectionViewTemplate.Title;
                    dataCollectionService.SaveDataCollectionViewTemplate(dataCollectionViewTemplate);
                }
                else
                {
                    dataCollectionService.Save(dataCollection);
                }

                DataCollection result = dataCollectionService.FindByName(dataCollectionInfo.Name);

                return result;
            }
            else
            {
                //没有要发布的属性，直接返回空
                return null;
            }
        }

        //PUT https://www.xx.com/dataWarehouse/v1/dataCollection/{dataCollectionName}
        [Route("v1/dataCollection/{dataCollectionName}")]
        public void Delete(string dataCollectionName)
        {
            dataCollectionService.Delete(dataCollectionName);
        }

        //PUT https://www.xx.com/dataWarehouse/v1/dataCollection/{dataCollectionName}
        //更新已经存在的dataCollectionInfo
        [Route("v1/dataCollection")]
        public BaseInfo Put(DataCollectionInfo dataCollectionInfo)
        {
            if (dataCollectionInfo == null || dataCollectionInfo.Name == null)
            {
                return null;
            }

            DataCollection dataCollectionExist = dataCollectionService.FindByName(dataCollectionInfo.Name);
            if (dataCollectionExist != null)
            {
                //先删除再创建
                dataCollectionService.Delete(dataCollectionInfo.Name);

            }

            //数据不存在则创建
            DataCollection dataCollection = CreateDataCollection(dataCollectionInfo);
            if (dataCollection == null)
            {
                return null;//发布的DataView有不存在的
            }
            return BindToViewModel(dataCollection);

        }

        private BaseInfo BindToViewModel(DataCollection dataCollection)
        {
            BaseInfo info = new BaseInfo();
            info.Name = dataCollection.Name;
            info.CreatedTime = dataCollection.CreatedTime;
            return info;
        }

        //private DataCollection AddPropertiesToDataCollection(DataCollectionInfo dataCollectionInfo)
        //{
        //    DataView dataView = dataViewService.FindByName(dataCollectionInfo.DataViewName);
        //    //第二步,发布的表不存在需要给出错误提示信息
        //    if (dataView == null)
        //    {
        //        return null;
        //    }

        //    Iesi.Collections.Generic.ISet<DataViewProperty> resultSet = dataView.Properties;

        //    DataCollection dataCollection = new DataCollection();
        //    Iesi.Collections.Generic.ISet<DataViewProperty> addProperty = new Iesi.Collections.Generic.HashedSet<DataViewProperty>();
        //    if ("*".Equals(dataCollectionInfo.DataViewProperties))
        //    {
        //        addProperty.AddAll(resultSet);
        //    }
        //    else
        //    {
        //        string[] tmp = dataCollectionInfo.DataViewProperties.Split(',');
        //        List<string> dataViewPropertyList = new List<string>(tmp);

        //        if (resultSet.Count < dataViewPropertyList.Count)
        //        {
        //            throw new ArgumentException("dataViewProperty error!");
        //        }

        //        List<string> nameList = new List<string>();

        //        foreach (DataViewProperty dataViewProperty in resultSet)
        //        {
        //            nameList.Add(dataViewProperty.Name);
        //        }

        //        foreach (string str in dataViewPropertyList)
        //        {
        //            if (!nameList.Contains(str))
        //            {
        //                throw new ArgumentException("dataViewProperty error!");
        //            }
        //        }
        //        foreach (DataViewProperty dataViewProperty in resultSet)
        //        {
        //            if (dataViewPropertyList.Contains(dataViewProperty.Name))
        //            {
        //                addProperty.Add(dataViewProperty);
        //            }
        //        }
        //    }
        //    dataCollection.DataViewProperties = addProperty;
        //    dataCollection.DataView = dataView;
        //    return dataCollection;
        //}

        //private DataCollection CreateDataCollection(DataCollectionInfo dataCollectionInfo)
        //{
        //    //验证查询策略是否合法
        //    if (!CheckQueryPolicy(dataCollectionInfo.QueryPolicy))
        //    {
        //        //参数不合法
        //        return null;
        //    }
        //    QueryPolicyType queryPolicyType = (QueryPolicyType)Enum.Parse(typeof(QueryPolicyType), dataCollectionInfo.QueryPolicy);
        //    //添加属性到DataCollection
        //    DataCollection dataCollection = AddPropertiesToDataCollection(dataCollectionInfo);
        //    if (dataCollection==null)
        //    {
        //        return null;
        //    }
        //    dataCollection.Name = dataCollectionInfo.Name;
        //    dataCollection.QueryPolicyType = queryPolicyType;

        //    //add by 2014-07-08
        //    dataCollection.jump_url = dataCollectionInfo.jump_url;
        //    dataCollection.summary = dataCollectionInfo.summary;
        //    dataCollection.title = dataCollectionInfo.title;

        //    dataCollectionService.Save(dataCollection);

        //    return dataCollection;
        //}

        //private bool CheckQueryPolicy(string queryPolicyType)
        //{
        //    bool isOk = false;
        //    switch (queryPolicyType)
        //    {
        //        case "DataPool":
        //            isOk = true;
        //            break;
        //        case "DataSource":
        //            isOk = true;
        //            break;
        //        case "DataCache":
        //            isOk = true;
        //            break;
        //    }
        //    return isOk;
        //}
    }
}